package cn.bytest.netty.serialize;

import cn.bytets.rpc.api.serialize.ObjectOutput;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import java.io.*;

public class GsonOutput implements ObjectOutput {

    private final PrintWriter writer;

    private Gson gson = null;

    public GsonOutput(OutputStream out) {
        this(new OutputStreamWriter(out));
    }

    public GsonOutput(Writer writer) {
        this.gson = new GsonBuilder().
                registerTypeAdapter(Class.class, new JsonClassCodec())
                .create();
        this.writer = new PrintWriter(writer);
    }

    /**
     * Write boolean.
     *
     * @param v value.
     * @throws IOException
     */
    @Override
    public void writeBool(boolean v) throws IOException {
        writeObject(v);
    }

    /**
     * Write byte.
     *
     * @param v value.
     * @throws IOException
     */
    @Override
    public void writeByte(byte v) throws IOException {
        writeObject(v);
    }

    /**
     * Write short.
     *
     * @param v value.
     * @throws IOException
     */
    @Override
    public void writeShort(short v) throws IOException {
        writeObject(v);
    }

    /**
     * Write integer.
     *
     * @param v value.
     * @throws IOException
     */
    @Override
    public void writeInt(int v) throws IOException {
        writeObject(v);
    }

    /**
     * Write long.
     *
     * @param v value.
     * @throws IOException
     */
    @Override
    public void writeLong(long v) throws IOException {
        writeObject(v);
    }

    /**
     * Write float.
     *
     * @param v value.
     * @throws IOException
     */
    @Override
    public void writeFloat(float v) throws IOException {
        writeObject(v);
    }

    /**
     * Write double.
     *
     * @param v value.
     * @throws IOException
     */
    @Override
    public void writeDouble(double v) throws IOException {
        writeObject(v);
    }

    /**
     * Write string.
     *
     * @param v value.
     * @throws IOException
     */
    @Override
    public void writeUTF(String v) throws IOException {
        writeObject(v);
    }

    /**
     * Write byte array.
     *
     * @param v value.
     * @throws IOException
     */
    @Override
    public void writeBytes(byte[] v) throws IOException {
        writer.println(new String(v));
    }

    /**
     * Write byte array.
     *
     * @param v   value.
     * @param off the start offset in the data.
     * @param len the number of bytes that are written.
     * @throws IOException
     */
    @Override
    public void writeBytes(byte[] v, int off, int len) throws IOException {
        writer.println(new String(v, off, len));
    }

    /**
     * Flush buffer.
     *
     * @throws IOException
     */
    @Override
    public void flushBuffer() throws IOException {
        writer.flush();
    }

    /**
     * write object.
     *
     * @param obj object.
     */
    @Override
    public void writeObject(Object obj) throws IOException {
        char[] chars = gson.toJson(obj).toCharArray();
        writer.write(chars,0,chars.length);
        writer.println();
        writer.flush();
        gson = null;
    }
}
